<script setup lang="ts" name="FlowDesignOnekey">
import { computed, reactive, ref, getCurrentInstance, watch } from "vue";
import ProcessDesigner from "./process/ProcessDesigner.vue";
import ProcessBaseSetting from "./ProcessBaseSetting.vue";
import DesignerValidate from "./DesignerValidate.vue";
import { type DefFlowModel } from "./process/ProcessDef";
import { addOrUpdateObj } from "@/api/flow/def/";
import { getObj } from "@/api/flow/form";
import { useMessage } from "@/hooks/message";
import { cloneObject } from "@/utils/common";

const _this = getCurrentInstance();
const active = ref("BASE");
const processValidateRef = ref(null);

const activeDesign = computed(() => {
  console.log("activeDesign", active.value === "BASE");
  return active.value === "PROCESS";
});

const validRefs = ref([
  { _ref: "base", name: "基础设置", status: "" },
  { _ref: "process", name: "流程设计", status: "" }
]);

//设计器数据
const designData = reactive({
  def: {
    id: "",
    flowName: "未命名流程",
    flowKey: "",
    icon: {
      name: "file-icons:omnigraffle",
      bgc: "#4C87F3",
      color: "#FFFFFF"
    },
    formId: "",
    formName: "",
    status: "-1",
    version: 1,
    sort: 1,
    groupId: "1",
    remark: null
  } as DefFlowModel,
  formDef: {
    conf: {
      labelPosition: "right", //标签位置
      labelWidth: 80, //标签宽度，
      size: "default"
    },
    components: []
  },
  //流程json
  flowDef: []
});

watch(
  () => designData.def.formId,
  val => {
    getObj(val).then(res => {
      if (res.code === 200) {
        if (res.data && res.data.formInfo) {
          cloneObject(designData.formDef, JSON.parse(res.data.formInfo));
        }
      }
    });
  }
);

function switchMenu(index) {
  if (active.value === "BASE") {
    const compRef = _this.refs[validRefs.value[0]._ref] as any;
    compRef
      .validate()
      .then(() => {
        active.value = index;
      })
      .catch(() => {
        active.value = "BASE";
        return false;
      });
  } else {
    active.value = index;
  }
}

function handleSave() {
  designData.def.status = "-1";
  processValidateRef.value
    .validate(designData.def.status)
    .then(() => {
      processValidateRef.value.reloadValidResult(true);
    })
    .catch(errs => {
      processValidateRef.value.reloadValidResult(false);
      const validIndex = processValidateRef.value.getValidIndex();
      validRefs.value[validIndex].status = "error";
      if (Array.isArray(errs)) {
        processValidateRef.value.addValidResult(errs);
      }
    });
}

function handlePublish() {
  designData.def.status = "1";
  processValidateRef.value
    .validate(designData.def.status)
    .then(() => {
      processValidateRef.value.reloadValidResult(true);
    })
    .catch(errs => {
      processValidateRef.value.reloadValidResult(false);
      const validIndex = processValidateRef.value.getValidIndex();
      validRefs.value[validIndex].status = "error";
      if (Array.isArray(errs)) {
        processValidateRef.value.addValidResult(errs);
      }
    });
}

const saveOrPublish = () => {
  const params = {
    def: designData.def,
    formDef: JSON.stringify(designData.formDef),
    flowDef: JSON.stringify(designData.flowDef)
  };
  addOrUpdateObj(params)
    .then(res => {
      if (res.code === 200) {
        designData.def.id = res.data.id;
        if (!designData.def.formId) {
          designData.def.formId = res.data.formId;
          designData.def.formName = res.data.flowName + "表单";
        }
        useMessage().success("保存成功");
      } else {
        useMessage().success(res.msg);
      }
    })
    .catch(() => {
      useMessage().error("保存失败");
    });
};

const handleValidSuccess = () => {
  saveOrPublish();
};

const handleValidFail = step => {
  active.value = step;
};
</script>

<template>
  <div class="w-designer">
    <el-container>
      <el-header style="padding: 0">
        <el-menu
          :default-active="active"
          class="w-designer-menu"
          mode="horizontal"
          @select="switchMenu"
        >
          <div>
            <IconifyIconOnline
              :icon="designData.def.icon.name"
              class="w-process-icon"
              :style="{
                background: designData.def.icon.bgc,
                color: designData.def.icon.color
              }"
            />
            <el-text>{{ designData.def.flowName }}</el-text>
          </div>
          <el-menu-item index="BASE">① 基础设置</el-menu-item>
          <el-menu-item index="PROCESS">② 流程设计</el-menu-item>
          <div>
            <el-button icon="FolderChecked" round @click="handleSave">保存</el-button>
            <el-button icon="Promotion" type="primary" round @click="handlePublish">发布</el-button>
          </div>
        </el-menu>
      </el-header>
      <el-main
        :class="{
          'w-designer-container': true,
          'w-no-padding': active === 'FORM'
        }"
      >
        <ProcessBaseSetting
          v-show="active === 'BASE'"
          ref="base"
          v-model:defFlow="designData.def"
        />
        <ProcessDesigner
          v-show="activeDesign"
          ref="process"
          v-model="designData.flowDef"
          v-model:defFlow="designData.def"
          :active="activeDesign"
        />
      </el-main>
    </el-container>
    <DesignerValidate
      ref="processValidateRef"
      v-model:validRefs="validRefs"
      :instance="_this"
      @success="handleValidSuccess"
      @fail="handleValidFail"
    />
  </div>
</template>

<style lang="scss" scoped>
.w-designer {
  background: $main-bgc;
  width: 100%;
  height: 100%;

  .w-designer-menu {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    background: white;

    & > div:first-child {
      position: absolute;
      left: 20px;
      display: flex;
      align-items: center;

      .w-process-icon {
        margin: 0 10px 0 20px;
      }
    }

    & > div:last-child {
      position: absolute;
      right: 20px;
    }
  }

  .w-designer-container {
    height: calc(100vh - 60px);
    padding: 5px !important;
    overflow: hidden;
  }

  .w-no-padding {
    padding: 0;
  }
}
</style>
